package net.sample.gismeteo.svc;

import java.util.Observable;
import java.util.Observer;

import net.sample.gismeteo.Common;
import net.sample.gismeteo.R;
import net.sample.gismeteo.net.WeatherRetrievalHttpClient;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.widget.RemoteViews.ActionException;

/**
 * The background service for weather forecast retrieving. 
 * @author vkozlov
 * @version $Id: $
 */
public class WeatherRetrievalService extends Service implements Observer {

	private static final String TAG = "WeatherRetrievalServiceStarter";
	//private static final String PREF_FILE_NAME = "PrefFile";

	private WeatherRetrievalHttpClient mRetrieveClient;
	private String mForecastPreviousXML;
	private String mForecastLatestXML = null; 

	/**
	 * Event handler for service binding.
	 * @param intent the binding intent.
	 */
	@Override
	public IBinder onBind(Intent intent) {
		Log.d(TAG, "Service onBind.");
		return mBinder;
	}
	
	/**
	 * The binder interface.
	 */
	private final IWeatherServiceConnector.Stub mBinder = new IWeatherServiceConnector.Stub() {

		public String getLatestForecastXML() throws RemoteException
		{
			return loadLatest();
		}

		public Uri getLatestForecastURI() throws RemoteException
		{
			return null;
		}

	};
	private ContentResolver mResolver;

	/**
	 * Event handler for service create event.
	 */
	@Override
	public void onCreate() {
		super.onCreate();
		Log.d(TAG, "Service started.");
		mResolver = getContentResolver();
		//SharedPreferences prefs = getSharedPreferences(PREF_FILE_NAME, MODE_WORLD_READABLE);
		//mForecastPreviousXML = prefs.getString("WEATHER_XML", null);
		//mForecastPreviousXML = loadLatest();
		mRetrieveClient = new WeatherRetrievalHttpClient(this);
		mRetrieveClient.start();
	}

	
	
	/**
	 * Event handler for service destroy event.
	 */
	@Override
	public void onDestroy() {
		super.onDestroy();
		Log.d(TAG, "Service destroyed.");
		if (mRetrieveClient != null) {
			mRetrieveClient.stop();
		}
	}

	/**
	 * This method notifies observers about new forecast.
	 * @param observable the observable object
	 * @param data the data associated with notification
	 */
	public void update(Observable observable, Object data)
	{
		if (data != null)
		{
			Uri lUri = null;
			boolean lNeedNotif = false;
			mForecastLatestXML = data.toString();
			Log.d(TAG, "Observable update:" + mForecastLatestXML);
			if (null == mForecastPreviousXML)
			{
				mForecastPreviousXML = loadLatest();
				lNeedNotif = true;
			}
			if (!mForecastLatestXML.equals(mForecastPreviousXML))
			{
				lUri = saveEntry(mForecastLatestXML);
				mForecastPreviousXML = mForecastLatestXML;
				lNeedNotif = true;
			}
			if ((lNeedNotif) && (null != lUri))
			{
				fireNotification(lUri);
			}
		}
	}

	private Uri saveEntry(String pWeatherXML)
	{
		ContentValues lVals = new ContentValues();
		lVals.put(Common.COL_TS, System.currentTimeMillis());
		lVals.put(Common.COL_BODY, pWeatherXML);
		return mResolver.insert(Common.CONTENT_URI, lVals);
	}

	private String loadLatest()
	{
		String lResult = null;
		Cursor lCursor = mResolver.query(
				Common.CONTENT_URI
				, Common.PROJECTION
				, null, null
				, Common.COL_TS + " desc limit 1");
		if ((null != lCursor) && (lCursor.getCount() > 0)) 
		{
			lCursor.moveToFirst();
			lResult = lCursor.getString(lCursor.getColumnIndexOrThrow(Common.COL_BODY));
			lCursor.close();
		}
		return lResult;
	}
	
	/**
	 * Put notification into notification manager.
	 * @param pUri the XML-formatted weather forecast.
	 */
	private void fireNotification(Uri pUri)
	{
		NotificationManager mNM;
		mNM = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
		int lDrawableResID = R.drawable.icon;
		String lMessage = "Weather forecast retrieved";
		int lID = 100;

		
		Notification notification = new Notification(lDrawableResID, lMessage, System.currentTimeMillis());
		notification.setLatestEventInfo(this
				, "Gismeteo Weather"
				, "New forecast received"
				, PendingIntent.getActivity(
						this.getBaseContext()
						, 0
						, new Intent(Intent.ACTION_VIEW, pUri)
						, PendingIntent.FLAG_CANCEL_CURRENT
					)
			);
		notification.flags = Notification.FLAG_AUTO_CANCEL;
		mNM.notify(lID, notification);
	}

}
